/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FOUNDATION_ALIYUN_SRC_REALTIME_AUDIO_TRANSCODER_H_
#define FOUNDATION_ALIYUN_SRC_REALTIME_AUDIO_TRANSCODER_H_

#include <memory>
#include <vector>
#include <cstdint>
#include "utils_noncopyable.h"

namespace El {

// 前向声明
namespace Muxer {
class AacPcmDecoder;
class PcmAacEncoder;
} // namespace Muxer

namespace Cloud {

/**
 * @brief 实时音频转码器
 *
 * 提供双向音频转码功能:
 * 1. AAC -> PCM (16kHz): 用于发送给阿里云Qwen3-Omni模型
 * 2. PCM (24kHz) -> AAC: 用于播放云端返回的音频
 *
 * 使用场景:
 * - 从 media_stream 获取的 AAC 音频转换为 PCM 发送给云模型
 * - 云模型返回的 PCM 音频转换为 AAC 用于 media_speak 播放
 */
class RealtimeAudioTranscoder {
    DISALLOW_COPY_AND_MOVE(RealtimeAudioTranscoder);

public:
    /**
     * @brief 构造函数
     */
    RealtimeAudioTranscoder();

    /**
     * @brief 析构函数
     */
    ~RealtimeAudioTranscoder();

    /**
     * @brief 初始化转码器
     *
     * @return true=成功, false=失败
     */
    bool Initialize();

    /**
     * @brief AAC解码为PCM (用于发送给云模型)
     *
     * @param aacData AAC编码数据(ADTS格式)
     * @param pcmData 输出的PCM数据(16kHz, 16bit, 单声道)
     * @return true=成功, false=失败
     */
    bool DecodeAacToPcm(const std::vector<uint8_t> &aacData, std::vector<uint8_t> &pcmData);

    /**
     * @brief PCM编码为AAC (用于播放云端返回的音频)
     *
     * @param pcmData PCM数据(云端返回采样率, 16bit, 单声道)
     * @param aacData 输出的AAC数据(ADTS格式, 16kHz)
     * @return true=成功, false=失败
     */
    bool EncodePcmToAac(const std::vector<uint8_t> &pcmData, std::vector<uint8_t> &aacData);

    /**
     * @brief 刷新解码器缓冲区
     *
     * @param pcmData 输出剩余的PCM数据
     * @return true=成功, false=失败
     */
    bool FlushDecoder(std::vector<uint8_t> &pcmData);

    /**
     * @brief 刷新编码器缓冲区
     *
     * @param aacData 输出剩余的AAC数据
     * @return true=成功, false=失败
     */
    bool FlushEncoder(std::vector<uint8_t> &aacData);

    /**
     * @brief 重新配置云端音频到AAC的编码器
     *
     * @param inputSampleRate 云端返回PCM的采样率(Hz)
     * @param outputSampleRate 目标AAC采样率(Hz), 默认16kHz
     * @return true=成功, false=失败
     */
    bool ReconfigurePlaybackEncoder(int inputSampleRate, int outputSampleRate = 16000);

private:
    // AAC -> PCM 解码器 (用于输入到云模型)
    std::unique_ptr<El::Muxer::AacPcmDecoder> aacDecoder_;

    // PCM -> AAC 编码器 A/B 双实例 (用于播放云端返回的音频)
    std::unique_ptr<El::Muxer::PcmAacEncoder> encoderA_;
    std::unique_ptr<El::Muxer::PcmAacEncoder> encoderB_;
    El::Muxer::PcmAacEncoder *activeEncoder_{nullptr};
    El::Muxer::PcmAacEncoder *standbyEncoder_{nullptr};

    int playbackInputSampleRate_{24000};
    int playbackOutputSampleRate_{8000};
    int playbackBitrate_{64000};

    bool initialized_{false};

    // 内部辅助：同时配置两个编码器
    bool ConfigureEncoders(int inputSampleRate, int outputSampleRate);

public:
    /**
     * @brief 段尾快速切换：刷新当前活动编码器并切换到备用编码器
     *
     * @param tailAac 输出尾部 AAC 数据
     * @return true 成功
     */
    bool FlushActiveAndRotate(std::vector<uint8_t> &tailAac);
};

} // namespace Cloud
} // namespace El

#endif // FOUNDATION_ALIYUN_SRC_REALTIME_AUDIO_TRANSCODER_H_
